/*
 * Created by JFormDesigner on Thu Jan 20 22:35:44 ART 2011
 */

package main;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.ResourceBundle;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTabbedPane;
import javax.swing.JTextPane;
import javax.swing.border.EmptyBorder;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Caret;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;
import javax.swing.text.View;

import org.jdesktop.swingx.VerticalLayout;

import sl.com.sl.StripesImageDialog;
import sl.com.sl.data.CSExchange;
import sl.com.sl.data.CSExchangeImpl;

import ar.com.visualAORE.controller.ReqInternalFrameController;
import ar.com.visualAORE.model.Document;
import ar.com.visualAORE.model.Selection;
import ar.com.visualAORE.util.BlinkPainter;
import ar.com.visualAORE.util.ButtonsGraphics;
import ar.com.visualAORE.util.TextLineNumber;
import ar.com.visualAORE.util.UnderlineHighlightPainter;
import ar.com.visualAORE.view.VisualDesktopFrame;


/**
 * @author Brainrain
 */
public class ReqInternalFrame extends JInternalFrame {
	private static final long serialVersionUID = 1L;
	private static final int SEPARACION = 24;
	static int inset = 0;
	ReqInternalFrameController controller;
	VisualDesktopFrame vdf;
	Highlighter highlighter;
	Document document = null;
	double scale = 1.0;
	TextLineNumber tln;
	
	CSExchange data;
	//Text
	JFrame f = new JFrame();
    JEditorPane tp = new JEditorPane();
    
    
	
	public ReqInternalFrame() {
		initComponents();
		this.sliderThreshold.setEnabled(false);
		 setLocation(SEPARACION*inset, SEPARACION*inset);
	        ++inset;
	    this.tln = new TextLineNumber(this.textPane1);
	}
	public ReqInternalFrame(VisualDesktopFrame vdf, ReqInternalFrameController controller) {
        super(null,true,true,true,true);
        this.controller = controller;
        this.vdf = vdf;
        initComponents();
        initZoomSlider();
        this.data = new CSExchangeImpl(this.textPane1);
        
        this.highlighter = textPane1.getHighlighter();
        int chWidth = (int) vdf.getWidth()*55/100;
        int chHeight = (int) vdf.getHeight()*50/100;
        
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-chWidth)/2, (screenSize.height-chHeight)/2, chWidth, chHeight);
        setLocation(SEPARACION*inset, SEPARACION*inset);
        ++inset;
    //    this.textPane1.setContentType("text/html"); 
        this.textPane1.setCaretPosition(0);
        textPane1.setEditable(false);
        
        //Test
        tp.setEditable(false);
        //tp.setContentType("text/html");

        f.add(tp, BorderLayout.CENTER);
        f.setVisible(true);
        f.setSize(400,500);
	}
	/**
	 * Retorna el JTextPane del JInternalFrame
	 * @return jTextPane
	 */
	public JEditorPane getJtextPane(){
		return this.textPane1;
	}

	private void textPane1MouseReleased(MouseEvent e) {
		// TODO add your code here
		System.out.println(textPane1.getSelectedText());
		
		

		Caret seleccion = textPane1.getCaret();

		
		if (seleccion.getDot() == seleccion.getMark())
		{
		   // No hay nada seleccionado
		}
		else if(vdf.getCurrentCocnern() != null) //Significa que hay un concern seleccionado para poder pintar
		{
			
		//	String textoTotal = textPane1.getText();
		    vdf.setPainter(new UnderlineHighlightPainter(vdf.getCurrentCocnern().getColor()));	
		    
		    try {
				if(seleccion.getDot() > seleccion.getMark()){
					highlighter.addHighlight(seleccion.getMark(), seleccion.getDot(), vdf.getPainter());
					//this.controller.addSelection(new Selection(seleccion.getMark(), seleccion.getDot(), vdf.getCurrentCocnern(), textPane1.getSelectedText().length(), getLineNumber(textPane1, textPane1.getCaretPosition())), this.getTitle());
					System.out.println("DOT: " + seleccion.getDot());
					System.out.println("MARK: " + seleccion.getMark());
					System.out.println("LINENUMBER: " + getLineNumber(textPane1, textPane1.getCaretPosition()));
					System.out.println("MAGIC CARET " +seleccion.getMagicCaretPosition());
					//Para el blink
					try {
			            addBlink(seleccion.getMark(), seleccion.getDot(),vdf.getCurrentCocnern().getColor(), 300);
			        }
			        catch (BadLocationException ex) {
			            ex.printStackTrace();
			        }
				}
				else{
					highlighter.addHighlight(seleccion.getDot(), seleccion.getMark(), vdf.getPainter());
					//this.controller.addSelection(new Selection(seleccion.getDot(), seleccion.getMark(), vdf.getCurrentCocnern(), textPane1.getSelectedText().length(), getLineNumber(textPane1, textPane1.getCaretPosition())), this.getTitle());
					//Para el blink
					try {
			            addBlink(seleccion.getDot(), seleccion.getMark(),vdf.getCurrentCocnern().getColor(), 300);
			        }
			        catch (BadLocationException ex) {
			            ex.printStackTrace();
			        }
			     //  tp.getHighlighter().addHighlight(seleccion.getDot(), seleccion.getMark(), new BlinkPainter(vdf.getCurrentCocnern().getColor(), 300, tp));
			          
			           
			        
				}
				textPane1.setSelectionEnd(seleccion.getDot());
				textPane1.setSelectionStart(seleccion.getMark());
				
		    } catch (BadLocationException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
		    }
		}
	}
	/**
	 * Pinta un requerimiento a partir de su archivo xml
	 * @param document
	 */
	public void applyDocumentLayer(Document document){
		this.document = document;
		Iterator<Selection> it = document.getSelections().iterator();
		while(it.hasNext()){
			Selection selection = it.next();
			vdf.setPainter(new UnderlineHighlightPainter(selection.getConcern().getColor()));	
			try {
				highlighter.addHighlight(selection.getDot(), selection.getMark(), vdf.getPainter());
			} catch (BadLocationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public void goToSpecificPosition(int position){
		textPane1.setCaretPosition(position); 
		scrollPane1.setViewportView(textPane1);
	}

	private void sliderThresholdStateChanged(ChangeEvent e) {
		label2.setText(String.valueOf(sliderThreshold.getValue()) + "%");

	}

	private void sliderZoomStateChanged(ChangeEvent e) {
		// TODO add your code here
		 int value = sliderZoom.getValue();
         scale = (value+4)/20.0;
         revalidate();
         repaint();
	}
	public JSlider getZoomSlider(){
		return this.sliderZoom;
	}
	private void buttonApplyThresZoomActionPerformed(ActionEvent e) {
		if(this.document != null){
			//scrollPane1.setViewportView(new ButtonsGraphics(this.document, this, this.sliderZoom.getValue(), this.sliderThreshold.getValue()));
			System.out.println("SLIDERZOOM: " + this.sliderZoom.getValue());
		}
	}
	private void initZoomSlider(){
		 int min = 1, max = 10, inc = 1;
		 sliderZoom.setMinimum(min);
		 sliderZoom.setMaximum(max);
		 sliderZoom.setValue(inc);
		 sliderZoom.setMajorTickSpacing(5);
		 sliderZoom.setMinorTickSpacing(1);
		 sliderZoom.setPaintTicks(true);
		 sliderZoom.setSnapToTicks(true);
		 sliderZoom.setLabelTable(getLabelTable(min, max, inc));
		 sliderZoom.setPaintLabels(true);
	}
	 private Hashtable getLabelTable(int min, int max, int inc) {
	        Hashtable<Integer,JLabel> table = new Hashtable<Integer,JLabel>();
	        for(int j = min; j <= max; j += inc) {
	            //String s = String.format("%.2f", (j+4)/20.0);
	            table.put(Integer.valueOf(j), new JLabel("x" + String.valueOf(j)));
	        }
	        return table;
	 }
	 /**
	   * Return an int containing the wrapped line index at the given position
	   * @param component JTextPane
	   * @param int pos
	   * @return int
	   */
	  public int getLineNumber(JTextPane component, int pos) 
	  {
	    int posLine;
	    int y = 0;

	    try
	    {
	      Rectangle caretCoords = component.modelToView(pos);
	      y = (int) caretCoords.getY();
	    }
	    catch (BadLocationException ex)
	    {
	    }

	    int lineHeight = component.getFontMetrics(component.getFont()).getHeight();
	    posLine = (y / lineHeight) + 1;
	    return posLine;
	  }

	  /** 
	   * get Line Count 
	   *  
	   * @param str 
	   * @return the count of '\n' in the String 
	   */ 
	  public int getLineCount(String str){ 
	      String tempStr1 = new String(str.toLowerCase());
	      String tempStr2 = new String(str.toLowerCase());
	      String tempStr3 = new String(str.toLowerCase());
	      
	      int index; 
	      int lineCount = 0; 
	      while (tempStr1.length() > 0){ 
	    	  index = tempStr1.indexOf("<br>"); 
	    	  if(index != -1){ 
	    		  lineCount++; 
	    		  tempStr1 = tempStr1.substring(index+1); 
	    	  } 
	    	  else{ 
	    		  break; 
	    	  } 
	      } 
	      while (tempStr2.length() > 0){ 
	    	  index = tempStr2.indexOf("<p>"); 
	    	  if(index != -1){ 
	    		  lineCount++; 
	    		  tempStr2 = tempStr2.substring(index+1); 
	    	  } 
	    	  else{ 
	    		  break; 
	    	  } 
	      } 
	      while (tempStr3.length() > 0){ 
	    	  index = tempStr3.indexOf("<p>"); 
	    	  if(index != -1){ 
	    		  lineCount++; 
	    		  tempStr3 = tempStr3.substring(index+1); 
	    	  } 
	    	  else{ 
	    		  break; 
	    	  } 
	      } 
	      return lineCount; 
	   } 
	  public static int getWrappedLines(JTextComponent component)
	  {
	  int lines = 0;
	  View view = component.getUI().getRootView(component).getView(0);
	  int paragraphs = view.getViewCount();
	  for (int i = 0; i < paragraphs; i++)
	  {
	  lines += view.getView(i).getViewCount();
	  }
	  return lines;
	  }
	  private void textPane1CaretUpdate(CaretEvent e) {
		  labelLineNumber.setText("Line Number: " + getLineNumber(textPane1, textPane1.getCaretPosition()));
	  }
	  
	  //Test
	  @Override  
	    public void paint(Graphics g) {  
	        super.paint(g);  
	        final FontMetrics fontMetrics = g.getFontMetrics();  
	        // get width of any char (font is monospaced)  
	        final int charWidth = fontMetrics.charWidth('M');  
	        final int charHeight = fontMetrics.getHeight();  
	        final int prefWidth = this.getPreferredSize().width;  
	        // get height of Parent (JScrollPane)  
	        final int prefHeight = this.getParent().getHeight();  
	         
	        int maxChars = prefWidth/charWidth;  
	        int maxLines = prefHeight/charHeight;  
	    }  
	  
	  private void radioTextActionPerformed(ActionEvent e) {
		  // TODO add your code here
		scrollPane1.setViewportView(textPane1);
		this.textControls(true);
		this.mapControls(false);
		System.out.println("TOTAL LINENUMBERS: " + getLineCount(textPane1.getText()));
		System.out.println("TOTAL WrappedLines: " + getWrappedLines(textPane1));
		
	  }

	  private void radioMapActionPerformed(ActionEvent e) {
		  // TODO add your code here
		  
		  JFrame jf = new JFrame();
		  jf.setVisible(true);
		  StripesImageDialog dlg = new StripesImageDialog(jf, this.data);
		 // dlg.setLocation(this.getX() + this.getWidth(), this.getY() + tb.getHeight());
		  dlg.setVisible(true);
		  
		if(this.document != null){
			//scrollPane1.setViewportView(new ButtonsGraphics(this.document, this, 1, 2));
			this.mapControls(true);
			this.textControls(false);
		}
	  }
	  public JRadioButton getRadioButtonText(){
		  return this.radioText;
	  }
	  
	  //Muestra u oculta los controles para el mapa
	  public void mapControls(boolean flag){
		  this.buttonApplyThresZoom.setVisible(flag);
		  this.tabbedPaneConcernThreshold.setVisible(flag);
	  }
	  
	  public void textControls(boolean flag){
		  this.buttonExport.setVisible(flag);
		  this.labelLineNumber.setVisible(flag);
	  }
	  public void addBlink(int startPos, int endPos, Color blinkColor, int blinkRate) throws BadLocationException {
		  textPane1.getHighlighter().addHighlight(startPos, endPos, new BlinkPainter(blinkColor, blinkRate, textPane1));
	  }
	  
	private void initComponents() {
		// JFormDesigner - Component initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents
		ResourceBundle bundle = ResourceBundle.getBundle("locale");
		dialogPane = new JPanel();
		contentPanel = new JPanel();
		scrollPane1 = new JScrollPane();
		textPane1 = new JTextPane();
		labelLineNumber = new JLabel();
		buttonBar = new JPanel();
		this2 = new JPanel();
		tabbedPaneConcernThreshold = new JTabbedPane();
		panel1 = new JPanel();
		label1 = new JLabel();
		sliderThreshold = new JSlider();
		label2 = new JLabel();
		panel2 = new JPanel();
		sliderZoom = new JSlider();
		buttonApplyThresZoom = new JButton();
		panel3 = new JPanel();
		radioText = new JRadioButton();
		radioMap = new JRadioButton();
		buttonExport = new JButton();

		//======== this ========
		setVisible(true);
		setPreferredSize(new Dimension(451, 370));
		Container contentPane = getContentPane();
		contentPane.setLayout(new BorderLayout());

		//======== dialogPane ========
		{
			dialogPane.setBorder(new EmptyBorder(12, 12, 12, 12));
			dialogPane.setLayout(new BorderLayout());

			//======== contentPanel ========
			{
				contentPanel.setLayout(new BorderLayout());

				//======== scrollPane1 ========
				{

					//---- textPane1 ----
					textPane1.setPreferredSize(new Dimension(100, 100));
					textPane1.addMouseListener(new MouseAdapter() {
						@Override
						public void mouseReleased(MouseEvent e) {
							textPane1MouseReleased(e);
						}
					});
					textPane1.addCaretListener(new CaretListener() {
						public void caretUpdate(CaretEvent e) {
							textPane1CaretUpdate(e);
						}
					});
					scrollPane1.setViewportView(textPane1);
				}
				contentPanel.add(scrollPane1, BorderLayout.CENTER);

				//---- labelLineNumber ----
				labelLineNumber.setText(bundle.getString("labelLineNumber.text"));
				labelLineNumber.setForeground(Color.red);
				contentPanel.add(labelLineNumber, BorderLayout.NORTH);
			}
			dialogPane.add(contentPanel, BorderLayout.CENTER);

			//======== buttonBar ========
			{
				buttonBar.setBorder(new EmptyBorder(12, 0, 0, 0));
				buttonBar.setLayout(new GridBagLayout());
				((GridBagLayout)buttonBar.getLayout()).columnWidths = new int[] {0, 0, 0, 0, 85, 85, 0};
				((GridBagLayout)buttonBar.getLayout()).columnWeights = new double[] {0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0};

				//======== this2 ========
				{
					this2.setLayout(new VerticalLayout());

					//======== tabbedPaneConcernThreshold ========
					{
						tabbedPaneConcernThreshold.setToolTipText(bundle.getString("tabbedPaneConcernThreshold.toolTipText"));
						tabbedPaneConcernThreshold.setPreferredSize(new Dimension(268, 85));

						//======== panel1 ========
						{
							panel1.setLayout(new FlowLayout());

							//---- label1 ----
							label1.setText(bundle.getString("label1.text"));
							panel1.add(label1);

							//---- sliderThreshold ----
							sliderThreshold.setToolTipText(bundle.getString("sliderThreshold.toolTipText"));
							sliderThreshold.setValue(0);
							sliderThreshold.addChangeListener(new ChangeListener() {
								public void stateChanged(ChangeEvent e) {
									sliderThresholdStateChanged(e);
								}
							});
							panel1.add(sliderThreshold);

							//---- label2 ----
							label2.setText(bundle.getString("label2.text"));
							panel1.add(label2);
						}
						tabbedPaneConcernThreshold.addTab(bundle.getString("panel1.tab.title"), panel1);


						//======== panel2 ========
						{
							panel2.setLayout(new BorderLayout());

							//---- sliderZoom ----
							sliderZoom.setToolTipText(bundle.getString("sliderZoom.toolTipText"));
							sliderZoom.setPreferredSize(new Dimension(253, 16));
							sliderZoom.setValue(1);
							sliderZoom.addChangeListener(new ChangeListener() {
								public void stateChanged(ChangeEvent e) {
									sliderZoomStateChanged(e);
								}
							});
							panel2.add(sliderZoom, BorderLayout.CENTER);
						}
						tabbedPaneConcernThreshold.addTab(bundle.getString("panel2.tab.title"), panel2);

					}
					this2.add(tabbedPaneConcernThreshold);

					//---- buttonApplyThresZoom ----
					buttonApplyThresZoom.setText(bundle.getString("buttonApplyThresZoom.text"));
					buttonApplyThresZoom.addActionListener(new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							buttonApplyThresZoomActionPerformed(e);
						}
					});
					this2.add(buttonApplyThresZoom);
				}
				buttonBar.add(this2, new GridBagConstraints(0, 0, 5, 1, 0.0, 0.0,
					GridBagConstraints.CENTER, GridBagConstraints.BOTH,
					new Insets(0, 0, 0, 5), 0, 0));

				//======== panel3 ========
				{
					panel3.setLayout(new VerticalLayout());

					//---- radioText ----
					radioText.setText(bundle.getString("radioText.text"));
					radioText.addActionListener(new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							radioTextActionPerformed(e);
						}
					});
					panel3.add(radioText);

					//---- radioMap ----
					radioMap.setText(bundle.getString("radioMap.text"));
					radioMap.addActionListener(new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							radioMapActionPerformed(e);
						}
					});
					panel3.add(radioMap);

					//---- buttonExport ----
					buttonExport.setText(bundle.getString("buttonExport.text"));
					panel3.add(buttonExport);
				}
				buttonBar.add(panel3, new GridBagConstraints(5, 0, 1, 1, 0.0, 0.0,
					GridBagConstraints.CENTER, GridBagConstraints.BOTH,
					new Insets(0, 0, 0, 5), 0, 0));
			}
			dialogPane.add(buttonBar, BorderLayout.SOUTH);
		}
		contentPane.add(dialogPane, BorderLayout.CENTER);

		//---- buttonGroup1 ----
		ButtonGroup buttonGroup1 = new ButtonGroup();
		buttonGroup1.add(radioText);
		buttonGroup1.add(radioMap);
		// JFormDesigner - End of component initialization  //GEN-END:initComponents
	}

	// JFormDesigner - Variables declaration - DO NOT MODIFY  //GEN-BEGIN:variables
	private JPanel dialogPane;
	private JPanel contentPanel;
	private JScrollPane scrollPane1;
	private JTextPane textPane1;
	private JLabel labelLineNumber;
	private JPanel buttonBar;
	private JPanel this2;
	private JTabbedPane tabbedPaneConcernThreshold;
	private JPanel panel1;
	private JLabel label1;
	private JSlider sliderThreshold;
	private JLabel label2;
	private JPanel panel2;
	private JSlider sliderZoom;
	private JButton buttonApplyThresZoom;
	private JPanel panel3;
	private JRadioButton radioText;
	private JRadioButton radioMap;
	private JButton buttonExport;
	// JFormDesigner - End of variables declaration  //GEN-END:variables
}
